/* Orbas:
 *     A open source CORBA Specification implementation from Huihoo.
 *
 * Copyright 2002-2003 Huihoo.org, Inc. All Right Reserved.
 *
 * This software is licensed under LGPL license.
 * See terms of license at gnu.org.
 *
 * For more information, visit:
 *
 * http://www.huihoo.org/orbas
 */

package org.huihoo.orbas.orb;

/**
 * <p>Description: </p>
 * Object reference class.
 * <p>Copyright (c) 2002,2003</p>
 * <p>Company: <a href="http://www.huihoo.org/">huihoo.org</a></p>
 * @author <a href="http://www.huihoo.org/~mep">mep(mep@huihoo.com)</a>
 * @see <a href="http://www.huihoo.org/orbas">http://www.huihoo.org/orbas</a>
 * @version 1.0
 */

import org.huihoo.orbas.orb.ior.IorParser;
import org.omg.IOP.IOR;

public class ObjRefDelegate extends org.omg.CORBA_2_3.portable.Delegate {
	private ORB orb;
	private IorParser parser;
	// private IOR ior;
	private boolean isLocal = false;
	ClientWorker worker;

	public ObjRefDelegate(ORB orb, IorParser parser) {
		this.parser = parser;
		this.orb = orb;
		// worker = orb.getDefaultClientWorker();

	}

	public IorParser getParser() {
		return parser;
	}

	public synchronized org.omg.CORBA.Object duplicate(org.omg.CORBA.Object self) {
		return self;
	}

	public void release(org.omg.CORBA.Object self) {
	}

	public IOR getIor() {
		IOR ior = new IOR();

		ior.type_id = parser.getTypeId();
		ior.profiles = parser.getProfiles();

		return ior;
	}

	//
	// public void setIor(IOR ior) {
	// this.ior = ior;
	// }

	public org.omg.CORBA.portable.OutputStream request(
			org.omg.CORBA.Object self, String the_operation,
			boolean responseExpected) {

		return request(self, the_operation, responseExpected,
				parser.getVersion());
	}

	public boolean is_a(org.omg.CORBA.Object self, String repository_id) {
		ObjectImpl impl = (ObjectImpl) self;
		ObjRefDelegate delegate = (ObjRefDelegate) impl._get_delegate();

		if (parser.isA(repository_id))
			return true;
		org.omg.CORBA.portable.OutputStream out = request(self, "_is_a", true);
		out.write_string(repository_id);
		try {
			org.omg.CORBA.portable.InputStream result = invoke(self, out);
			return result.read_boolean();
		} catch (Exception e) {
		}
		return false;
	}

	public org.omg.CORBA.portable.OutputStream request(
			org.omg.CORBA.Object self, String the_operation,
			boolean responseExpected, int version) {

		org.omg.GIOP.TargetAddress targetObject = new org.omg.GIOP.TargetAddress();
		targetObject.object_key(parser.getObjectKey());
		// org.omg.IOP.TaggedProfile[] profiles = parser.getProfiles();
		// targetObject.profile(profiles[0]);
		if (worker == null) {
			if (version == 0) {
				version = orb.getDefaultGiopVersion();
			}
			worker = orb.getDefaultClientWorker(version);
		}
		return worker.createRequest(parser.getAddress(), targetObject,
				the_operation, responseExpected);
	}

	public org.omg.CORBA.Request create_request(org.omg.CORBA.Object self,
			org.omg.CORBA.Context ctx, String operation,
			org.omg.CORBA.NVList arg_list, org.omg.CORBA.NamedValue result) {
		throw new org.omg.CORBA.NO_IMPLEMENT();
	}

	public org.omg.CORBA.Request create_request(org.omg.CORBA.Object self,
			org.omg.CORBA.Context ctx, String operation,
			org.omg.CORBA.NVList arg_list, org.omg.CORBA.NamedValue result,
			org.omg.CORBA.ExceptionList exclist,
			org.omg.CORBA.ContextList ctxlist) {
		throw new org.omg.CORBA.NO_IMPLEMENT();
	}

	public org.omg.CORBA.Request request(org.omg.CORBA.Object self,
			String operation) {
		throw new org.omg.CORBA.NO_IMPLEMENT();
	}

	public org.omg.CORBA.portable.InputStream invoke(org.omg.CORBA.Object self,
			org.omg.CORBA.portable.OutputStream os)
			throws org.omg.CORBA.portable.ApplicationException,
			org.omg.CORBA.portable.RemarshalException {
		return worker.invoke(os);
	}

	public boolean is_equivalent(org.omg.CORBA.Object self,
			org.omg.CORBA.Object obj) {

		if (self == obj) {
			return true;
		}

		try {
			org.omg.CORBA.portable.ObjectImpl me = (org.omg.CORBA.portable.ObjectImpl) self;

			org.omg.CORBA.portable.ObjectImpl other = (org.omg.CORBA.portable.ObjectImpl) obj;

			String[] id1 = me._ids();
			String[] id2 = other._ids();

			for (int i = 0; i < id1.length; i++) {
				for (int j = 0; j < id2.length; j++) {
					if (id1[i].equals(id2[j])) {
						return true;
					}
				}
			}

		} catch (Exception ex) {

		}

		return false;
	}

	public org.omg.CORBA.InterfaceDef get_interface(org.omg.CORBA.Object self) {
		throw new org.omg.CORBA.NO_IMPLEMENT();
	}

	public boolean non_existent(org.omg.CORBA.Object self) {
		org.omg.CORBA.portable.OutputStream out = request(self,
				"_non_existent", true);
		try {
			org.omg.CORBA.portable.InputStream result = invoke(self, out);
			return result.read_boolean();
		} catch (Exception e) {
		}
		return false;
	}

	public boolean is_local(org.omg.CORBA.Object self) {
		return false;
	}

	// public Transport getConnection() {
	// return null;
	// }

	public int hash(org.omg.CORBA.Object self, int max) {
		return parser.getTypeId().hashCode();
	}

	public String toString() {
		if (parser != null) {

			return parser.toString();
		}
		return null;
	}

	public void releaseReply(org.omg.CORBA.Object self,
			org.omg.CORBA.portable.InputStream is) {
		return;
	}
}
